A Numbers Game

© 2005, Grahame King

NL139 Home

::::::::::::::::::::::::::::::::::::::::::::::::::::

Working with Strings - 2

Releasing Your Software

A Numbers Game

Native Lines

Precision Numbers

Graphicbox With Scrollbars

Using Wire

::::::::::::::::::::::::::::::::::::::::::::::::::::

Submission Guildlines

Newsletter Help

Index


Sliding Tiles

I remember a puzzle fad back in the 50s when I was growing up in Australia. Simply a square plastic board which held 15 plastic numbered tiles in a 4x4 array - leaving one cell empty to allow the tiles to be slid around with your finger. It was marketed in Australia at that time under the name Numero. You could give the puzzle to a friend and ask them to scramble the numbers by sliding them around. Then your goal was to slide the numbers back into the original order. Some versions could be tinkered with by prying them open and your friend might pull out two adjacent tiles and interchange them rendering the puzzle impossible to solve. Perhaps you know this puzzle under another name.

One Sunday recently I spent hours coding up a version of this puzzle. It was a nice way to spend some time after a frustrating week.

Here's what I came up with. Enjoy!



' The old "Numero" puzzle - Grahame King
' moves are just drag and drop with no animation

nomainwin
dim cell(3,3)
dim numLabel(3,3)

WindowWidth=300
WindowHeight=300

UpperLeftX=int((DisplayWidth-WindowWidth)/2)
UpperLeftY=int((DisplayHeight-WindowHeight)/2)

ULx = (WindowWidth-200)/2
ULy = (WindowHeight-250)/2

graphicbox #main.box ULx,ULy,200,200

menu #main, "Menu", _
"scramble", [scramble],_
"reset", [reset],_
"quit", [quit]

open "Numero" for window_nf as #main
#main "trapclose [quit]"
#main.box "font Times_New_Roman 14"

global tileColor$, backingColor$
tileColor$ = " 255 255 210"
backingColor$ = " 175 175 130"

[reset]
' initialize position of numbers
num = 1
for j = 0 to 3
for i = 0 to 3
' store num
cell(i,j) = num
num = num+1
next i
next j
' this makes cell(3,3)=16, representing the empty cell
emptyCellX = 3
emptyCellY = 3

[showNumbers]
' show numbers
for j = 0 to 3
for i = 0 to 3
' draw and label cell(i,j)
call drawCell i, j
next i
next j
#main.box "when leftButtonDown [selectNumber]"
#main.box "when leftButtonMove [moveNumber]"
#main.box "when leftButtonUp [releaseNumber]"
wait

[selectNumber]
' first find cell ID
x = MouseX : y = MouseY
xNum = int(x/50)
yNum = int(y/50)
wait

[moveNumber]
' animation, if any, goes here
wait

[releaseNumber]
' first find new cell ID
x = MouseX : y = MouseY
xNewNum = int(x/50)
yNewNum = int(y/50)
if xNewNum>-1 and xNewNum<4 and yNewNum>-1 and yNewNum<4 then ' to prevent moves off the board
if abs(xNewNum-xNum)+abs(yNewNum-yNum)<2 then    ' to rule out diagonal moves
gosub [move]
end if
end if
wait

[scramble]
' make a series of random moves
' first get random seed
randSeed = (val(word$(time$(),3,":"))+1)/65
randomize randSeed
for k = 1 to 184
' pick a cell adjacent to the empty cell at random
NS=0 :EW=0
while abs(NS)+abs(EW)=0   ' try again if no step either way
do
rand = rnd(1)
NS = int(3*rand)-1 ' random step of -1, 0 or +1
rand = rnd(1)
EW = int(3*rand)-1 ' random step of -1, 0 or +1
loop until NS=0 or EW=0   ' to rule out diagonal moves
wend
xNewNum = emptyCellX
yNewNum = emptyCellY
trialxNum = emptyCellX+EW
trialyNum = emptyCellY+NS
' move the tile from that cell into the vacant cell if its a legal move
if trialxNum>-1 and trialxNum<4 and trialyNum>-1 and trialyNum<4 then ' adjacent cell must be on board
xNum = trialxNum
yNum = trialyNum
gosub [move]
end if
next k
wait

[quit]
close #main
end

[move]
if cell(xNewNum,yNewNum)=16 then
' move is legal - moving into empty slot
cell(xNewNum,yNewNum) = cell(xNum,yNum)
call drawCell xNewNum, yNewNum
cell(xNum,yNum) = 16
print "setting ",xNum, yNum, "->",16
call drawCell xNum, yNum
emptyCellX = xNum
emptyCellY = yNum
xNum = xNewNum : yNum = yNewNum
end if
return
sub drawCell i, j
x = 50*i : y = 50*j
#main.box "place ";x;" ";y
#main.box "down"
x = x+49 : y = y+49
if cell(i,j)=16 then
' black out the cell to represent missing number
#main.box "backcolor ";backingColor$
#main.box "boxfilled ";x;" ";y
else
#main.box "backcolor ";tileColor$
#main.box "boxfilled ";x;" ";y
label$ = using("###",cell(i,j))
#main.box "stringwidth? label$ width"
#main.box "place ";x-50+width/2;" ";y-20
#main.box "\";label$
end if
#main.box "flush"
end sub


DEMO

The file numero.bas is included in the zipped archive of this newsletter.


NL139 Home

::::::::::::::::::::::::::::::::::::::::::::::::::::

Working with Strings - 2

Releasing Your Software

A Numbers Game

Native Lines

Precision Numbers

Graphicbox With Scrollbars

Using Wire

::::::::::::::::::::::::::::::::::::::::::::::::::::

Submission Guildlines

Newsletter Help

Index